//
// Created by Administrator on 2021/5/15.
//
#include <string>
#include <iostream>
#include <unordered_map>

using namespace std;

class Solution {
public:
    int romanToInt(string s) {
        unordered_map<char, int> map1{{'I', 1},
                                      {'V', 5},
                                      {'X', 10},
                                      {'L', 50},
                                      {'C', 100},
                                      {'D', 500},
                                      {'M', 1000}};
        unordered_map<string, int> map2{
                {"IV", -2},
                {"IX", -2},
                {"XL", -20},
                {"XC", -20},
                {"CD", -200},
                {"CM", -200}
        };
        int ans = 0;
        int n = s.size() - 1;
        while (n >= 0) {
            ans += map1[s[n]];
            if (n != 0) {
                string word;
                word.push_back(s[n - 1]);
                word.push_back(s[n]);
                if (map2.find(word) != map2.end()) {
                    ans += map1[s[n - 1]] + map2[word];
                    --n;
                }
            }
            --n;
        }
        return ans;
    }
};

class Solution2 { // 题解
private:
    unordered_map<char, int> symbolValues = {
            {'I', 1},
            {'V', 5},
            {'X', 10},
            {'L', 50},
            {'C', 100},
            {'D', 500},
            {'M', 1000},
    };

public:
    int romanToInt(string s) {
        int ans = 0;
        int n = static_cast<int>(s.length());
        for (int i = 0; i < n; ++i) {
            int value = symbolValues[s[i]];
            if (i < n - 1 && value < symbolValues[s[i + 1]]) { // 如果比右边的数小，则取反
                ans -= value;
            } else {
                ans += value;
            }
        }
        return ans;
    }
};

class Solution3 { // 优秀解答
public:
    int romanToInt(string s) {
        int ans = 0, pre = 99999, now, len = s.length();
        for (int i = 0; i < len; ++i) {
            now = value(s[i]);
            // cout<<"pre: "<<pre<<" now:  "<<now<<endl;
            if (now > pre) {
                ans -= 2 * pre;
                ans += now;
                continue;
            }
            ans += now;
            pre = now;
        }
        return ans;
    }

    inline int value(char a) {
        switch (a) {
            case 'I':
                return 1;
            case 'V':
                return 5;
            case 'X':
                return 10;
            case 'L':
                return 50;
            case 'C':
                return 100;
            case 'D':
                return 500;
            case 'M':
                return 1000;
            default:
                return -1;
        }
    }
};

int main() {
    Solution3 sol;
    cout << sol.romanToInt("LVIII") << endl;
    cout << sol.romanToInt("MCMXCIV") << endl;
    return 0;
}